<?php
namespace App\GraphQL\Mutations\Group;

use App\Models\GroupPolicy;
use App\Models\GroupPolicyRule;
use GraphQL\Type\Definition\ResolveInfo;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Nuwave\Lighthouse\Support\Contracts\GraphQLContext;

class UpdatePolicy
{

    public function __invoke($rootValue, array $args, GraphQLContext $context, ResolveInfo $resolveInfo)
    {
        $id = $args['id'];
        $data = $args['input'];
        $authUser = auth()->user();
        $data['resource_cate'] = $authUser->role_code == 'ADMIN' ? 'CURRENT' : 'CUSTOM';
        $policy = $this->validate($id, $data);
        $distributors = collect($data['distributors'])->map(function ($item, $index) {
            $item['sort'] = $index;
            $item['cate'] = 'DISTRIBUTOR';
            $item['scale'] = intval($item['scale'] * 100);
            return $item;
        });
        $merchants = collect($data['merchants'])->map(function ($item, $index) {
            $item['sort'] = $index;
            $item['cate'] = 'MERCHANT';
            $item['scale'] = intval($item['scale'] * 100);
            return $item;
        });
        $staffs = collect($data['staffs'])->map(function ($item, $index) {
            $item['sort'] = $index;
            $item['cate'] = 'STAFF';
            $item['scale'] = intval($item['scale'] * 100);
            return $item;
        });
        $deviceRules = $distributors->concat($merchants);
        if ($deviceRules->sum('scale') > 10000) {
            throw new \Exception('设备分组分成比例不能超过100%');
        }
        if ($merchants->count() > 1) {
            throw new \Exception('终端伙伴只能有一个!');
        }
        if ($staffs->sum('scale') > 10000) {
            throw new \Exception('分润员工分成比例不能超过100%');
        }
        $allRules = $deviceRules->concat($staffs)->map(function ($item) use($policy) {
            // 查询当前索引 的记录是否存在 存在则更新
            $old = $policy->rules()->where('cate',$item['cate'])->where('sort',$item['sort'])->first();
            if($old){
                $old->scale = $item['scale'];
                $old->name = $item['name'];
                return $old;
            }
            return new GroupPolicyRule($item);
        });
        // 创建策略
        $policy->update([
            'name' => $data['name'],
            'cate' => $data['cate'],
            'resource_cate' => $data['resource_cate']
        ]);
        
        // 删除分销商规则
        $distributorLastItem = $distributors->last();
        if ($distributorLastItem){
            $policy->rules()->where('cate','DISTRIBUTOR')->where('sort','>',$distributorLastItem['sort'])->delete();
        }
        
        // 删除终端伙伴规则
        $merchantLastItem = $merchants->last();
        if ($merchantLastItem){
            $policy->rules()->where('cate','MERCHANT')->where('sort','>',$merchantLastItem['sort'])->delete();
        }
        // 删除分润员工规则
        $staffLastItem = $merchants->last();
        if ($staffLastItem){
            $policy->rules()->where('cate','STAFF')->where('sort','>',$staffLastItem['sort'])->delete();
        }
        $policy->rules()->saveMany($allRules);
        return [
            'status' => '200',
            'message' => '更新成功'
        ];
    }

    public function validate($id, $data)
    {
        $authUser = auth()->user();
        $cates = [
            'DEVICE'
        ];
        if ($authUser->role_code == 'MERCHANT') {
            $cates = [
                'STAFF'
            ];
        }
        $rules = [
            'name' => [
                'required',
                'max:18'
            ],
            'cate' => [
                'required',
                Rule::in($cates)
            ],
            'resource_cate' => [
                'required',
                Rule::in([
                    'CURRENT',
                    'CUSTOM'
                ])
            ],
            'distributors' => [
                'nullable',
                'array'
            ],
            'merchants' => [
                'nullable',
                'array'
            ],
            'staffs' => [
                'nullable',
                'array'
            ],
            'distributors.*.name' => [
                'required'
            ],
            'distributors.*.scale' => [
                'required',
                'numeric',
                'min:0',
                'max:100'
            ],
            'merchants.*.name' => [
                'required'
            ],
            'merchants.*.scale' => [
                'required',
                'numeric',
                'min:0',
                'max:100'
            ],
            'staffs.*.name' => [
                'required'
            ],
            'staffs.*.scale' => [
                'required',
                'numeric',
                'min:0',
                'max:100'
            ]
        ];
        $messages = [
            'name.required' => '名称不能为空',
            'name.max' => '名称不能超过18个字',
            'cate.required' => '分类不能为空',
            'resource_cate.required' => '内容分组不能为空',
            'resource_cate.in' => '内容分组不能超出限制',
            'cate.in' => '分类不能超出限制',
            'distributors.array' => '分销商规则为数组',
            'merchants.array.required' => '终端伙伴规则为数组',
            'distributors.*.name.required' => '分销商规则名称不能为空',
            'merchants.*.name.required' => '终端伙伴规则名称不能为空',
            'staffs.*.name.required' => '分润员工规则名称不能为空',
            'distributors.*.scale.required' => '分销商规则比例不能为空',
            'merchants.*.scale.required' => '终端伙伴规则比例不能为空',
            'staffs.*.scale.required' => '分润员工规则比例不能为空',
            'distributors.*.scale.numeric' => '分销商规则比例为数字',
            'merchants.*.scale.numeric' => '终端伙伴规则比例为数字',
            'staffs.*.scale.numeric' => '分润员工规则比例为数字',
            'distributors.*.scale.min' => '分销商规则比例不能为负数',
            'merchants.*.scale.min' => '终端伙伴规则比例不能为负数',
            'staffs.*.scale.min' => '分润员工规则比例为不能为负数',
            'distributors.*.scale.max' => '分销商规则比例不能大于100%',
            'merchants.*.scale.max' => '终端伙伴规则比例不能大于100%',
            'staffs.*.scale.max' => '分润员工规则比例不能大于100%'
        ];
        $validate = Validator::make($data, $rules, $messages);
        if ($validate->fails()) {
            throw new \InvalidArgumentException($validate->messages()->first());
        }
        $old = GroupPolicy::find($id);
        if (! $old) {
            throw new \Exception('策略不存在!');
        }
        return $old;
    }
}
